package com.xjh.basestudy.lanqiaobei;

import java.util.ArrayList;
import java.util.HashSet;

public class Collection_ {
    public static void main(String[] args) {
        c_2019_3();
        c_2015_6();
        c_2019_4();
    }

    private static void c_2019_4() {
        /**
         * - 质数就是只能被1和它本身整除的数字。最小的质数是2.
         * - 如何判断一个数字n是不是质数：找一下[2,n-1]有没有能被n整除的数字，有就不是质数。
         * - 整除：n对数字取余为0
         * 2019java C组第四题
         * 我们知道第一个质数是2，第二个质数是3 ， 第三个质数是5....
         * 请你计算第2023个质数？
         * 分析：我们可以先去求质数，然后把求到的质数放入一个list里面。取出下标为2022的，就是第2023个质数。
         * */
        long i = 3;
        ArrayList<Object> list = new ArrayList<>();
        list.add(2);//2 一定是质数
        while (true) {
            boolean isPrime = true;
//            判断当前遍历元素是否是质数
            for (int j = 2; j <= i - 1; j++) {

                if (i % j == 0) {
                    isPrime = false;
                }

            }
            if (isPrime) {
                list.add(i);
            }
            //                找到2023个后输出
            if (list.size() == 2023) {
                break;
            }
            i++;
        }
        System.out.println("第2023个质数" + list.get(2022));


//        法二：
//        ArrayList<Object> list = new ArrayList<>();
//        for (int i=2; i<=20000;i++){
//            int a =0;//记录有没有除了1和它本身之外的可以整除的数字。
//            for (int j =2 ; j<i;j++){
//                if(i%j ==0){
//                    a++;
//                    break;//只有找到一个能被整除的就退出内层循环，提高运算效率
//                }
//            }
//            if(a==0){
//                list.add(i);
//            }
//        }
//        System.out.println(list.get(2022));

    }

    private static void c_2015_6() {
        /**
         * 小明发现了一个奇妙的数字。它的平方和立方正好把 0 ~ 9 的 10 个数字每个用且只用了一次。你能猜出这个数字是多少吗？
         * 1. 平方和立方通过取模求出每一位（不推荐）
         * 2. 通过字符串操作，去求每一位，放入set，看长度是否为10
         *
         * */
        long n = 0;
        while (true) {
            long pingfang = n * n;
            long lifang = n * n * n;
            // 判断 立方和平方只包含10个不同的数字
            String str = String.valueOf(pingfang) + String.valueOf(lifang);
            if (str.length() == 10) {
//                或者拆分成字符数组加入set，且size还是10；
                if (str.contains("0") && str.contains("1") && str.contains("2") && str.contains("3") && str.contains("4") && str.contains("5") && str.contains("6") && str.contains("7") && str.contains("8") && str.contains("9")) {
                    break;
                }
            }
            n++;
        }
        System.out.println("小明发现了一个奇妙的数字。它的平方和立方正好把 0 ~ 9 的 10 个数字每个用且只用了一次。你能猜出这个数字是多少吗=" + n);

//        法二：用字符

        int i = 1;
        while (true) {
            HashSet<Object> set = new HashSet<>();
            int ping = i * i;
            int li = i * i * i;
            String string = "" + ping + li;
            if (string.length() == 10) {
                System.out.println(string);
                char[] cs = string.toCharArray();
                for (int j = 0; j < 10; j++) {
                    set.add(cs[j]);
                }
                if (set.size() == 10) {//找到了
                    System.out.println("找到了" + i);
                    break;
                }
            }
            i++;
        }
    }

    public static void c_2019_3() {
        /**
         * 一个字符串的非空子串是指字符串中长度至少为1的连续的一段字符组成的串。
         * 例如，字符串 aaab有非空子串 a, b, aa, ab, aaa, aab, aaab一共 7个。注意在计算时，只算本质不同的串的个数。
         * 请问，字符串 0100110001010001有多少个不同的非空子串？
         *
         * 分析：set的唯一性，去除重复的子串
         * - aaab从第一个下标开始截取: a aa aaa aaab
         * - 从第二个下标开始：a aa aab
         * - ......
         * - 下标0 截取的范围：[0,最大下标].
         * - 下标1的截取范围：[1,最大下标]
         * - .....
         * - 截取的方法：subString(i,j):截取子串
         *
         *
         * */
//        使用双循环指针的方法截取字符串，固定一个，移动一个。截取后加入set
        String str = "0100110001010001";
        System.out.println(str.substring(0, str.length() - 1));
        HashSet<Object> strSet = new HashSet<>();
        for (int i = 0; i < str.length(); i++) {
//            j从i+1开始，防止出现i>=j的情况
            for (int j = i + 1; j <= str.length(); j++) {
                String subStr = str.substring(i, j);
                strSet.add(subStr);
            }
        }
        System.out.println(strSet.size());
//法二：

        String string = "0100110001010001";
        HashSet<Object> set = new HashSet<>();//去重
        for (int i = 0; i < string.length(); i++) {//控制从第几个下标开始截取
            for (int j = i; j < string.length(); j++) {
                String s = string.substring(i, j + 1);
                set.add(s);
            }
        }
        System.out.println(set.size());

    }
}
